<template>
  <!-- 挂载元素 -->
  <section class="todoapp" id="app"> 
    <!-- 输入框区域 -->
    <header class="header">
      <h1>todos</h1>
      <input 
        class="new-todo" 
        placeholder="What needs to be done?" 
        autofocus 
        v-model.trim="newTodo" 
        @keyup.enter="addTodo" >
    </header>
    <!-- 事项列表区域 -->
    <section class="main" v-show="todos.length">
      <!-- 这里注意下 v-model不能使用表达式，可以用计算属性 -->
      <input id="toggle-all" class="toggle-all" type="checkbox" v-model="allDone">
      <label for="toggle-all">Mark all as complete</label>
      <ul class="todo-list">
        <!-- 已完成事项的 li -->
        <!-- <li class="completed">
          <div class="view">
            <input class="toggle" type="checkbox" checked>
            <label>Taste JavaScript</label>
            <button class="destroy"></button>
          </div>
          <input class="edit" value="Create a TodoMVC template">
        </li> -->
        <!-- 待办事项的 li -->
        <!-- <li>
          <div class="view">
            <input class="toggle" type="checkbox">
            <label>Buy a unicorn</label>
            <button class="destroy"></button>
          </div>
          <input class="edit" value="Rule the web">
        </li> -->
        <!-- editing 给当前编辑的内容加样式 , completed 添加删除线 -->
        <li 
          v-for="todo in filteredTodos" 
          :key="todo.id" 
          :class="{completed:todo.completed, editing:todo === editingTodo}">
          <div class="view">
            <!-- 这里用v-model不是v-bind，因为还要满足用户手动修改驱动数据变化。-->
            <!-- 注意，checkbox单选时v-model绑定的返回true或false表示是否勾选 -->
            <input class="toggle" type="checkbox" v-model="todo.completed">
            <label @dblclick="editTodo(todo)">{{ todo.title }}</label>
            <button class="destroy" @click="removeTodo(todo)"></button>
          </div>
          <!-- 修改时，设置autofocus无法让其自动获取焦点，此属性在编译时运行，刷新页面，此时这个input还没显示 -->
          <!-- 改用 自定义指令 是编辑的input则手动触发原生.focus() -->
          <input 
            class="edit" 
            v-model="todo.title" 
            v-todo-focus="todo === editingTodo" 
            @keyup.esc="cancelEdit(todo)"
            @keyup.enter="editDone(todo)"
            @blur="editDone(todo)">
        </li>

      </ul>
    </section>
    <!-- 状态栏区域 -->
    <footer class="footer" v-show="todos.length">
      <!-- remaining 计算属性 -->
      <span class="todo-count"><strong>{{ remaining }}</strong> {{ pluralize("item") }} left</span>
      <ul class="filters">
        <li>
          <a 
            href="#/all" 
            @click="todoType='all'" 
            :class="{selected:todoType==='all'}"
            >All</a>
        </li>
        <li>
          <a 
            href="#/active" 
            @click="todoType='active'" 
            :class="{selected:todoType==='active'}"
            >Active</a>
        </li>
        <li>
          <a 
            href="#/completed" 
            @click="todoType='completed'" 
            :class="{selected:todoType==='completed'}"
            >Completed</a>
        </li>
      </ul>
      <button 
        class="clear-completed" 
        v-show="doneNum" 
        @click="removeCompleted"
        >Clear completed</button>
    </footer>
  </section>
  <footer class="info">
    <p>Double-click to edit a todo</p>
    <!-- Remove the below line ↓ -->
    <p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p>
    <!-- Change this out with your name and url ↓ -->
    <p>Created by <a href="http://todomvc.com">mcgee0731</a></p>
    <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
  </footer>
</template>

<script>
import '../node_modules/todomvc-common/base.css'
import '../node_modules/todomvc-app-css/index.css'
import useLocalStorage from './utils/useLocalStorage'
import { ref, watchEffect,computed, onMounted, onUnmounted } from 'vue'

// 1. 新增数据
const useAdd = todos=>{
  const newTodo = ref('')
  const addTodo = ()=>{
    if(!newTodo.value) return
    todos.value.unshift({
      id:todos.value.length_1,
      title:newTodo.value,
      completed:false
    })
    newTodo.value = ''
  }
  return {
    newTodo,
    addTodo
  }
}

const filters = {
  all(todos){
    return todos
  },
  active(todos){
    return todos.filter(todo=>!todo.completed)
  },
  completed(todos){
    return todos.filter(todo=>todo.completed)
  }
}

// 2. 删除数据
const useRemove = todos=>{
  const removeTodo= todo=>{
    const index = todos.value.indexOf(todo)
    todos.value.splice(index,1)
  }
  const removeCompleted= ()=>{
    todos.value = filters.active(todos.value)
  }
  return {
    removeTodo,
    removeCompleted
  }
}

// 3. 编辑待办项
const useEdit = removeTodo=>{
  // 保存编辑之前的内容，便于还原
  let titleBeforeEdit= ''
  // 正在编辑的todo
  const editingTodo = ref(null)

  // 双击编辑
  const editTodo = todo=>{
    editingTodo.value = todo
    titleBeforeEdit = todo.title
  }

  // 取消编辑esc
  const cancelEdit = todo=>{
    editingTodo.value = null
    todo.title = titleBeforeEdit
  }

  // 确认编辑回车或失去焦点
  const editDone = todo=>{
    if(!editingTodo.value) return
    todo.title = todo.title.trim()
    // if(!todo.title){
      //   removeTodo(todo)
    // }
    // 写法2
    todo.title || removeTodo(todo)

    editingTodo.value = null
  }

  return {
    editingTodo,
    editTodo,
    cancelEdit,
    editDone
  }
}

// 4. 切换待办项
const useCheck = todos=>{
  // 待办个数
  const remaining = computed(()=>{
    return todos.value.filter(todo=>!todo.completed).length
  }) 
  // 全选
  const allDone = computed({
    get:()=>{
      return remaining.value === 0
    },
    set:(newVal)=>{
      todos.value.map(todo=>todo.completed = newVal)
    }
  })

  const pluralize = str=>{
    return str + (remaining.value<=1?"":"s")
  }

  // 切换的状态 All Active Completed
  const todoType = ref('all')

  const doneNum = computed(()=>{
    return todos.value.length > remaining.value
  })

	//------------------------------------------
  // 方式1：通过a 标签 hash 获取当前选择哪一项
  const onHashChange = ()=>{
    const hash = window.location.hash.replace("#/","")
    if(filters[hash]){
      todoType.value = hash
    }else{
      todoType.value = 'all'
      window.location.hash = ''
    }
  }

  onMounted(()=>{
    window.addEventListener('hashchange',onHashChange)
    onHashChange()
  })

  onUnmounted(()=>{
    window.removeEventListener("hashchange",onHashChange)
  })
  //------------------------------------------
  // 方式2 给a 标签设置 点击事件，手动修改 todoType
  // ...改 dom 标签
  //------------------------------------------

  // 当前根据切换状态要显示的列表
  const filteredTodos = computed(() => filters[todoType.value](todos.value))

  return {
    remaining,
    allDone,
    pluralize,
    filteredTodos,
    todoType,
    doneNum
  }
}


// 5. todos 数据，默认空，存储在 localStorage
const storage = useLocalStorage()
const useStorage = ()=>{
  const TODOS_KEY = "todos_vue"
  const todos = ref(storage.getItem(TODOS_KEY) || []) // 不存在取空
  watchEffect(()=>{
    storage.setItem(TODOS_KEY,todos.value)
  })
  return todos
}


export default {
  name: 'App',
  setup(){
    // const todos = reactive([
    //   {id:1,title:"吃饭",completed:true},
    //   {id:2,title:"睡觉",completed:false},
    //   {id:3,title:"打豆豆",completed:false}
    // ])
    const todos = useStorage()
    const { removeTodo, removeCompleted } = useRemove(todos)

    return {
      todos,
      ...useAdd(todos),
      removeTodo,
      removeCompleted,
      ...useCheck(todos),
      ...useEdit(removeTodo)
    }
  },
  directives:{
    todoFocus:(el,binding)=>{ // 'todo-focus'
      binding.value && el.focus()
        
    }
  }
}
</script>

<style>
</style>
